<?php

namespace App\V3\Api\Controllers;

use App\V3\Api\Models\MaterielsTypeModel;
use App\V3\Api\Models\StorageManageModel;
use App\V3\Api\Services\StorageManageService;
use App\Helper\Utils\Util;
use App\Http\Controllers\Api\CommonController;
use Exception;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Log;
use Illuminate\Validation\Rule;
use Illuminate\Support\Facades\Validator;
use App\V3\Api\Services\MaterielTypeService;
use App\Http\Controllers\Api\BaseController;
use App\V3\Api\Models\HcMaterielTypeModel;
use OSS\OssClient;

class MaterielTypeController extends BaseController
{
    /**
     * 创建物料商品信息
     * @param Request $request
     * AUTHOR  : Sun Wu
     * DateTime: 2022/3/4 15:51
     * @return \Illuminate\Http\JsonResponse
     */
    public function add(Request $request)
    {
        $validator = Validator::make($data = $request->all(), [
            'materiel_name' => 'required',//物料名称
//            'type_name' => 'required',//物料型号
            // 'materiel_img' => 'required',//物料图
            'materiel_no' => 'required',//物料编号
            'materiel_class_id' => [
                'required',
                'integer',
                Rule::notIn([0]),
            ],//物料类型所属二级分类id
            'length' => 'numeric|min:0',//长
            'width' => 'numeric|min:0',//宽
            'height' => 'numeric|min:0',//高
            'weight' => 'numeric|min:0',//体积
            'cost' => 'numeric|min:0',//成本
            'selling_price' => 'numeric|min:0',//销售价格
            'is_use_serial' => [
                Rule::in([0,1])
            ]
        ],
            [
                'materiel_name.required' => '请填写商品名称',
//                'type_name.required' => '请填写商品型号',
                'materiel_no.required' => '请填写商品编号',
                'materiel_class_id.required' => '请选择商品类型所属分类id',
                'length.numeric' => '商品长度只能为数字',
                'length.min' => '商品长度最小只能为0',
                'width.numeric' => '商品宽度只能为数字',
                'width.min' => '商品宽度最小只能为0',
                'height.numeric' => '商品高度只能为数字',
                'height.min' => '商品高度最小只能为0',
                'weight.numeric' => '商品体积只能为数字',
                'weight.min' => '商品体积最小只能为0',
                'cost.numeric' => '商品成本只能为数字',
                'cost.min' => '商品成本最小只能为0',
                'selling_price.numeric' => '销售价格只能为数字',
                'selling_price.min' => '销售价格最小只能为0',
                'is_use_serial.in' => '参数`是否使用序列号`不合法'
            ]
        );

        if ($info = $validator->errors()->first()) {
            return response()->json([
                'code' => 1,
                'msg' => $info,
                'data' => '',
            ]);
        }

        $data['length'] = isset($data['length'])?($data['length'] < 0)?0:$data['length']:0;
        $data['width'] = isset($data['width'])?($data['width'] < 0)?0:$data['width']:0;
        $data['height'] = isset($data['height'])?($data['height'] < 0)?0:$data['height']:0;
        $data['weight'] = isset($data['weight'])?($data['weight'] < 0)?0:$data['weight']:0;
        $data['cost'] = isset($data['cost'])?($data['cost'] < 0)?0:$data['cost']:0;
        $data['selling_price'] = isset($data['selling_price'])?($data['selling_price'] < 0)?0:$data['selling_price']:0;
        $data['lower_selling_price'] = isset($data['lower_selling_price'])?($data['lower_selling_price'] < 0)?0:$data['lower_selling_price']:0;

        $data['main_id'] = $this->getMainUserId();
        $data['created_at'] = time();
        $data['remark'] = empty($data['remark'])?'':$data['remark'];
        $data['materiel_img'] = empty($data['materiel_img'])?'':$data['materiel_img'];
        $data['attribute'] = empty($data['attribute'])?'':$data['attribute'];
        $data['type_name'] = empty($data['type_name'])?$data['materiel_name']:$data['type_name'];
        $data['materiel_thumbnail_img'] = empty($data['materiel_img'])?'':$data['materiel_img'].config('app.aliyun_oss_thumbnail_url');

        //检查物料商品编号是否存在
//        $checkNo = MaterielTypeService::checkNo($data);
//
//        if(!$checkNo) {
//            return $this->fail('', '商品编号已存在，请重新输入');
//        }

        //验证商品信息是否已存在
        $checkMaterielInfo = MaterielTypeService::checkMaterielInfo($data);
        if(!$checkMaterielInfo) {
            return $this->fail('', '物料类型`'.$data['materiel_name'].'-'.$data['type_name'].'`已存在');
        }

        $result = MaterielTypeService::add($data);

        if(!$result['code']) {
            $this->log('新建物料商品', $data);
            return $this->success(['id' => $result['data']]);
        }
        else {
            return $this->fail('', $result['msg']);
        }
    }

    public function del(Request $request)
    {
        if(empty($request->id)) {
            return $this->fail('', '参数`物料商品id`缺失');
        }

        $arr = array_filter(explode(',', $request->id), function($v) { return $v !== ''; });

        $checkTypeInfo = StorageManageModel::where('delete_flag', 0)
            ->where('in_storage_num', '!=', 0)
            ->whereIn('type_id', $arr)->first();

        if(!empty($checkTypeInfo)) {
            return $this->fail('', '若需要删除该物料类型，需删除该类型下所有的在库数据');
        }

        DB::beginTransaction();

        try {
            MaterielsTypeModel::whereIn('id', $arr)->update(['delete_flag' => 1]);
            StorageManageModel::where('in_storage_num', 0)->whereIn('type_id', $arr)->update(['delete_flag' => 1]);

            $this->log('删除物料类型', $arr);
            DB::commit();
            return $this->success();
        }
        catch(Exception $e) {
            DB::rollBack();
            return $this->fail('', $e->getMessage());
        }
    }

    /**
     * 删除指定商品信息
     * 废弃
     * 废弃时间 2022-08-23 17：52
     * @param Request $request
     * AUTHOR  : Sun Wu
     * DateTime: 2022/3/4 16:17
     * @return \Illuminate\Http\JsonResponse
     */
    public function del1(Request $request)
    {
        if(empty($request->id)) {
            return $this->fail('', '参数`物料商品id`缺失');
        }

        $checkMateriel = MaterielTypeService::checkMateriel(
            $this->getMainUserId(),
            $request->id
        );

        if(!$checkMateriel) {
            return $this->fail('', '您要删除的物料商品不存在，请重试');
        }

        $checkStorage = StorageManageService::checkMatierlInStorageOrNot(
            $request->id,
            $this->getMainUserId(),
        );

        if(!$checkStorage) {
            return $this->fail('', '若需要删除该物料商品，需删除库存中所有相关数据');
        }

        MaterielsTypeModel::where('id', $request->id)->update(['delete_flag' => 1]);

        $this->log('删除物料类型', $request->id);
        return $this->success();
    }

    /**
     * 编辑商品详细
     * @param Request $request
     * AUTHOR  : Sun Wu
     * DateTime: 2022/3/5 9:37
     * @return \Illuminate\Http\JsonResponse
     */
    public function edit(Request $request)
    {
        $validator = Validator::make($data = $request->all(), [
            'id' => 'required',//物料名称
            'materiel_name' => 'required',//物料名称
//            'type_name' => 'required',//物料型号
            // 'materiel_img' => 'required',//物料图
            'materiel_no' => 'required',//物料编号
            'materiel_class_id' => [
                'required',
                'integer',
                Rule::notIn([0]),
            ],//物料类型所属二级分类id
//            'length' => 'numeric|min:0',//长
//            'width' => 'numeric|min:0',//宽
//            'height' => 'numeric|min:0',//高
//            'weight' => 'numeric|min:0',//体积
//            'cost' => 'numeric|min:0',//成本
//            'selling_price' => 'numeric|min:0',//成本
        ],
            [
                'id.required' => '参数`物料商品id`缺失',
                'materiel_name.required' => '请填写商品名称',
//                'type_name.required' => '请填写商品型号',
                // 'materiel_img.required' => '请上传物料类型图',
                'materiel_no.required' => '请填写商品编号',
                'materiel_no.size' => '商品编号必须为8位',
                'materiel_class_id.required' => '请选择商品类型所属分类id',
//                'length.numeric' => '商品长度只能为数字',
//                'length.min' => '商品长度最小只能为0',
//                'width.numeric' => '商品宽度只能为数字',
//                'width.min' => '商品宽度最小只能为0',
//                'height.numeric' => '商品高度只能为数字',
//                'height.min' => '商品高度最小只能为0',
//                'weight.numeric' => '商品体积只能为数字',
//                'weight.min' => '商品体积最小只能为0',
//                'cost.numeric' => '商品成本只能为数字',
//                'cost.min' => '商品成本最小只能为0',
//                'selling_price.numeric' => '销售价格只能为数字',
//                'selling_price.min' => '销售价格最小只能为0',
            ]
        );

        if ($info = $validator->errors()->first()) {
            return response()->json([
                'code' => 1,
                'msg' => $info,
                'data' => '',
            ]);
        }

        $data['length'] = isset($data['length'])?($data['length'] < 0)?0:$data['length']:0;
        $data['width'] = isset($data['width'])?($data['width'] < 0)?0:$data['width']:0;
        $data['height'] = isset($data['height'])?($data['height'] < 0)?0:$data['height']:0;
        $data['weight'] = isset($data['weight'])?($data['weight'] < 0)?0:$data['weight']:0;
        $data['cost'] = isset($data['cost'])?($data['cost'] < 0)?0:$data['cost']:0;
        $data['selling_price'] = isset($data['selling_price'])?($data['selling_price'] < 0)?0:$data['selling_price']:0;
        $data['lower_selling_price'] = isset($data['lower_selling_price'])?($data['lower_selling_price'] < 0)?0:$data['lower_selling_price']:0;

        $data['main_id'] = $this->getMainUserId();
        $data['remark'] = empty($data['remark'])?'':$data['remark'];
        $data['materiel_img'] = empty($data['materiel_img'])?'':$data['materiel_img'];
        $data['materiel_thumbnail_img'] = empty($data['materiel_img'])?'':$data['materiel_img'].config('app.aliyun_oss_thumbnail_url');
        $data['attribute'] = empty($data['attribute'])?'':$data['attribute'];
        $data['type_name'] = empty($data['type_name'])?$data['materiel_name']:$data['type_name'];

        DB::beginTransaction();

        try {
            //检查物料商品编号是否存在
            $checkNo = MaterielTypeService::checkRandNo($data);
            if(!$checkNo) {
                return $this->fail('', '商品编号已存在，请重新输入');
            }

            //验证商品信息除己身外是否已存在
            $checkMaterielInfo = MaterielTypeService::checkMaterielInfoExceptSelf($data);
            if(!$checkMaterielInfo) {
                return $this->fail('', '物料类型`'.$data['materiel_name'].'-'.$data['type_name'].'`已存在');
            }

            $materielTypeInfo = MaterielsTypeModel::where('id', $data['id'])->first();
            if(!empty($materielTypeInfo['materiel_img'])) {
                $client = new OssClient(
                    config('app.aliyun_oss_key'),
                    config('app.aliyun_oss_secret'),
                    config('app.aliyun_oss_endpoint'),
                );

                $isHttpStart = substr($materielTypeInfo['materiel_img'], 0, 4);

                if($isHttpStart != 'http') {
                    if(file_exists(public_path().$materielTypeInfo['materiel_img'])) {
                        unlink(public_path().$materielTypeInfo['materiel_img']);
                    }
                }
                else {
                    $substrUrl = explode('uploads', $materielTypeInfo['materiel_img']);

                    $client->deleteObject(config('app.aliyun_oss_bucket'), 'uploads'.$substrUrl[1]);
                }
            }

            MaterielsTypeModel::where('id', $data['id'])->update($data);

            $storageManageInfo = StorageManageModel::where('type_id', $data['id'])->where('delete_flag', 0)->first();
            if(!empty($storageManageInfo)) {
                $storageManageInfo->materiel_mean_cost = $data['cost'];
                $storageManageInfo->save();
            }

//            unset($data['materiel_thumbnail_img']);

            HcMaterielTypeModel::where(['id'=>$data['id'],'main_id'=>$data['main_id']])->update($data);
            StorageManageModel::where('type_id', $data['id'])->update([
                'materiel_mean_cost' => $data['cost']
            ]);

            $this->log('编辑物料商品', $data);

            DB::commit();
            return $this->success();
        }
        catch(Exception $e) {
            DB::rollBack();
            Log::debug('编辑商品信息异常'.var_export($data, true));
            return $this->fail('', $e->getMessage());
        }
    }

    /**
     * 获取物料商品指定信息
     * @param Request $request
     * AUTHOR  : Sun Wu
     * DateTime: 2022/3/5 9:39
     * @return \Illuminate\Http\JsonResponse
     */
    public function info(Request $request)
    {
        if(empty($request->id)) {
            return $this->fail('', '参数`物料类型id`缺失');
        }

        return $this->success(
            MaterielTypeService::info(
                $request->id
            )
        );
    }

    /**
     * 物料列表
     * @param Request $request
     * AUTHOR  : Sun Wu
     * DateTime: 2022/3/5 10:39
     * @return \Illuminate\Http\JsonResponse
     */
    public function select(Request $request)
    {
        $keyword = empty($request->keyword)?'':$request->keyword;
        $condition = [];

        if(!empty($request->materiel_class_id)) {
            $condition['a.materiel_class_id'] = ['EQ' => $request->materiel_class_id];
        }

        return $this->success(
            MaterielTypeService::materielTypeSelect(
                $this->getMainUserId(),
                $keyword,
                $condition,
                $request->pageSize,
                $request->currentPage
            )
        );
    }

    /**
     * 物料商品列表-含库存信息
     * @param Request $request
     * AUTHOR  : Sun Wu
     * DateTime: 2022/3/5 11:22
     * @return \Illuminate\Http\JsonResponse
     */
    public function list(Request $request)
    {
        $validator = Validator::make($data = $request->all(), [
            'pageSize' => 'required',//物料名称
            'currentPage' => 'required',//成本
        ],
            [
                'pageSize.required' => '参数`页面大小`缺失',
                'currentPage.required' => '参数`页码`缺失',
            ]
        );

        if ($info = $validator->errors()->first()) {
            return response()->json([
                'code' => 1,
                'msg' => $info,
                'data' => '',
            ]);
        }
        if($this->getUserId() == $this->getMainUserId()) {
            $parentId['e.main_id'] = ['EQ' => $this->getMainUserId()];
        }
        else {
            if($this->isShareStorage()) {
                $parentId['e.main_id'] = ['EQ' => $this->getMainUserId()];
            }else {
                $parentId['e.user_id'] = ['EQ' => $this->getUserId()];
            }
        }
        return $this->success(
            MaterielTypeService::list(
                $parentId,
                $data
            )
        );
    }

    public function randNo()
    {
        $data['materiel_no'] = Util::randStr(8);
        $data['main_id'] = $this->getMainUserId();

        while(!empty(MaterielsTypeModel::checkMaterielTypeRandCode($data))) {
            $data['materiel_no'] = Util::randStr(8);
        }

        unset($data['main_id']);

        return $this->success($data);
    }

    public function editMaterielCost(Request $request)
    {
        $validator = Validator::make($data = $request->all(), [
            'id' => 'required',//物料名称
            'cost' => 'numeric|min:0',//成本
        ],
            [
                'id.required' => '参数`物料商品id`缺失',
                'cost.numeric' => '商品成本只能为数字',
                'cost.min' => '商品成本最小只能为0',
            ]
        );

        if ($info = $validator->errors()->first()) {
            return response()->json([
                'code' => 1,
                'msg' => $info,
                'data' => '',
            ]);
        }

        $this->log('修改成本价', $data);
        MaterielTypeService::editMaterielCost($data);
        return $this->success();
    }
}
